<template>
  <div class="tab-scaffold" ref="scaffoldRef">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="left">
        <slot name="toolbar-left" />
      </div>
      <div class="right">
        <slot name="toolbar-right" />
      </div>
    </div>

    <!-- 滚动区 -->
    <div class="table-area">
      <div class="table-scroll">
        <slot />
      </div>

      <!-- 粘底页脚（全选 + 分页 + 每页条数） -->
      <div class="table-footer" ref="footerRef">
        <div class="left">
          <a-checkbox :checked="checkAll" @change="$emit('check-all', $event)">全选</a-checkbox>
        </div>

        <div class="right">
          <span class="stat">本页 {{ pageCount }} 条 共 {{ safeTotal }} 条</span>

          <a-pagination :current="safeCurrent" :pageSize="safePageSize" :total="safeTotal" show-less-items
            show-quick-jumper @update:current="(v) => $emit('update:current', v)" />

          <a-dropdown placement="topRight" trigger="['click']">
            <a-button class="psize-btn">
              {{ safePageSize }} 条/页 <span class="caret">▾</span>
            </a-button>
            <template #overlay>
              <a-menu @click="onChooseSize">
                <a-menu-item v-for="opt in normalizedPageSizeOptions" :key="String(opt)">
                  {{ opt }} 条/页
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref, onMounted, onBeforeUnmount, nextTick } from "vue";

const props = withDefaults(
  defineProps<{
    current: number | string;
    pageSize: number | string;
    total: number | string;
    pageCount: number;
    checkAll: boolean;
    pageSizeOptions?: string[];
  }>(),
  { pageSizeOptions: () => ["10", "20", "50"] }
);

const emit = defineEmits<{
  (e: "update:current", v: number): void;
  (e: "update:pageSize", v: number): void;
  (e: "check-all", ev: any): void;
}>();

/** 安全数值 */
const toNum = (v: any, def: number) => {
  const n = Number(v);
  return Number.isFinite(n) && n > 0 ? n : def;
};
const safeCurrent = computed(() => toNum(props.current, 1));
const safePageSize = computed(() => toNum(props.pageSize, 10));
const safeTotal = computed(() => {
  const n = Number(props.total);
  return Number.isFinite(n) && n >= 0 ? n : 0;
});

/** 归一化 pageSize 选项 */
const normalizedPageSizeOptions = computed(() => {
  const list = (props.pageSizeOptions || [])
    .map((s) => Number(s))
    .filter((n) => Number.isFinite(n) && n > 0);
  return list.length ? list : [10, 20, 50];
});

/** 选择每页条数 */
function onChooseSize(info: { key: string }) {
  const n = Number(info?.key);
  if (Number.isFinite(n) && n > 0 && n !== safePageSize.value) {
    emit("update:pageSize", n);
  }
}

const footerRef = ref<HTMLElement | null>(null);
const scaffoldRef = ref<HTMLElement | null>(null);
let ro: ResizeObserver | null = null;

const applyFooterHeight = () => {
  nextTick(() => {
    const h = footerRef.value?.offsetHeight ?? 56; 
    scaffoldRef.value?.style.setProperty("--footer-h", `${Math.max(h, 48)}px`);
  });
};

onMounted(() => {
  applyFooterHeight();
  if ("ResizeObserver" in window && footerRef.value) {
    ro = new ResizeObserver(applyFooterHeight);
    ro.observe(footerRef.value);
  }
  window.addEventListener("resize", applyFooterHeight);
});

onBeforeUnmount(() => {
  ro?.disconnect();
  window.removeEventListener("resize", applyFooterHeight);
});
</script>

<style lang="less" scoped>
.tab-scaffold {
  --footer-h: 56px;

  background: #fff;
  border: 1px solid #eaeaea;
  border-radius: 6px;
  padding: 10px;

  display: flex;
  flex-direction: column;
  min-height: 83vh;
  min-width: 0;
}

/* 顶部工具栏 */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;

  .left :deep(.ant-btn) {
    padding: 0 14px;
    height: 30px;
    border-color: #1677ff;
    color: #1677ff;
  }

  .right {
    display: flex;
    align-items: center;
  }
}

/* 滚动容器 */
.table-area {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  /* Firefox */
  scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
  scrollbar-gutter: stable both-edges;
}

/* WebKit 滚动条美化 */
.table-area::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.table-area::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.15);
  border-radius: 6px;
  border: 2px solid transparent;
  background-clip: padding-box;
}

.table-area::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.25);
}

.table-area::-webkit-scrollbar-track {
  background: transparent;
}

.table-scroll {
  flex: 1 1 auto;
  min-height: 0;
  // padding-bottom: calc(var(--footer-h) + 12px);
}

/* 表格基础样式 */
:deep(.ant-table-thead > tr > th) {
  background: #f4f8fd;
  color: #333;
  border-color: #d9d9d9;
  font-weight: 600;
  height: 40px;
  padding: 8px 12px;
}

:deep(.ant-table-tbody > tr > td) {
  border-color: #d9d9d9;
  height: 40px;
  padding: 8px 12px;
}

/* 粘底页脚 */
.table-footer {
  position: sticky;
  bottom: 0;
  z-index: 2;

  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;

  padding: 10px 8px;
  border-top: 1px solid #eaeaea;
  background: #fff;
  flex-wrap: nowrap;

  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.03);

  .stat {
    margin-right: 12px;
    color: #666;
    white-space: nowrap;
  }

  .right {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-width: 0;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
  }
}

/* “条/页”按钮 */
.psize-btn {
  padding: 0 12px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.caret {
  font-size: 12px;
  color: #999;
}

</style>
